﻿using HomeCareLibrary.AppService;
using HomeCareLibrary.Constants;
using HomeCareLibrary.Core.DataContracts;
using System;
using System.Configuration;
using System.Linq;
using System.Web.Mvc;
using System.Web.SessionState;
using System.Web;
using HomeCareLibrary.Models;

namespace HomeCareLibrary.Filters
{
    /// <summary>
    /// The Filter class for checking the sponsor and updating the session based on that.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class CheckSponsorAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// Called by the ASP.NET MVC framework before the action method executes.
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (ConfigurationManager.AppSettings["EnableBaseControlling"] == "true")
            {
                // Check for promocode only when not already set.
                var session = filterContext.RequestContext.HttpContext.Session;
                if (session[SessionConstants.PROMO_CODE] == null)
                {
                    string requestDomain = filterContext.RequestContext.HttpContext.Request.Url.Host;
                    string sponsorCode = string.Empty;

                    // for bypassing local debug mode.
                    if (filterContext.RequestContext.HttpContext.Request.IsLocal)
                    {
                        requestDomain = "andyOnCall.home-wizard.com";
                    }

                    // Check for post data
                    // Get spronsor code from posted data
                    var postedPromoCode = filterContext.Controller.ValueProvider.GetValue(PostDataNameConstants.PROMO_CODE);
                    if (postedPromoCode == null)
                    {
                        postedPromoCode = filterContext.Controller.ValueProvider.GetValue(PostDataNameConstants.SPONSOR_CODE);
                    }
                    sponsorCode = postedPromoCode != null ? postedPromoCode.AttemptedValue : null;
                    if (string.IsNullOrEmpty(sponsorCode))
                    {
                        // When no posted data, check for querystring
                        sponsorCode = filterContext.RequestContext.HttpContext.Request.QueryString.AllKeys.FirstOrDefault();

                        if (string.IsNullOrWhiteSpace(sponsorCode))
                        {
                            // QS also not present, check for subdomain.
                            sponsorCode = requestDomain.Substring(0, requestDomain.IndexOf("."));
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(sponsorCode))
                    {
                        var sponsorService = new SponsorAppService();
                        var result = sponsorService.CheckPromoCode(new CheckPromocodeRequest
                        {
                            PromoCode = sponsorCode
                        });

                        if (result == null || !result.Any() || result.First().PromocodeCheck == "nothingSent")
                        {
                            // invalid promo code, need to show invalid code warning
                            filterContext.Controller.ViewBag.SponsorCodeCheck = "Invalid";
                        }
                        else
                        {
                            // Set the view bag with promocode chcek result.
                            var promoCodeResult = result.First();
                            filterContext.Controller.ViewBag.SponsorCodeCheck = promoCodeResult.PromocodeCheck;

                            // check if valid sponsor
                            if (promoCodeResult.PromocodeCheck == "foundInactive")
                            {
                                // inactive sponsor, null out session data.
                                session[SessionConstants.PROMO_CODE] = null;
                                session[SessionConstants.IS_PROMO_CODE_ACTIVE] = promoCodeResult.PromocodeCheck;
                            }
                            else
                            {
                                // update sponsor 345x input format data to session which will be used by most of the pages for updating the sponsor logo and other features
                                var sponsorSessionData = sponsorService.GetSponsorInput345xData(promoCodeResult.promocode);
                                session[SessionConstants.SPONSOR_DETAILS] = sponsorSessionData;

                                // Check Session user and promocode, if different update DB.
                                if (session[SessionConstants.USER_ID] != null && session[SessionConstants.USER_ID].ToString() != "-1") // -1 = Guest
                                {
                                    // check session promocode, if not already set or different update DB.
                                    if (session[SessionConstants.PROMO_CODE] == null || session[SessionConstants.PROMO_CODE].ToString() != promoCodeResult.promocode)
                                    {
                                        // Update DB.
                                        SponsorAppService service = new SponsorAppService();
                                        service.UpdateUserSponsorCode(int.Parse(session[SessionConstants.USER_ID].ToString()), promoCodeResult.promocode);
                                    }
                                }
                                
                                // Update session promocode.
                                session[SessionConstants.PROMO_CODE] = promoCodeResult.promocode;
                                session[SessionConstants.IS_PROMO_CODE_ACTIVE] = promoCodeResult.PromocodeCheck;
                            }
                        }
                    }
                }
            }
            else
            {
                // Base controller turned off, set fake user id and home number in session
                filterContext.RequestContext.HttpContext.Session[SessionConstants.USER_ID] = "14299";
                filterContext.RequestContext.HttpContext.Session[SessionConstants.HOME_NUMBER] = "1";
            }

            base.OnActionExecuting(filterContext);
        }
    }
}